package com.sz.biz.common.base.service.impl;

import com.sz.biz.common.constants.ErrorCodes;
import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.common.base.entity.Currency;
import com.sz.biz.common.base.entity.ExchangeRate;
import com.sz.biz.common.base.service.AreaService;
import com.sz.biz.common.base.service.CurrencyService;
import com.sz.biz.common.base.dto.CurrencyDto;
import com.sz.common.base.cache.EntityCache;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dao.DaoSupport;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.dto.CodeNameDto;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.service.PrincipalLogUtils;
import com.sz.common.core.service.PrincipalUtils;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Function: 货币 <br>
 * Author: xutao <br>
 * Date: 2016-11-21 09:45:00
 */
@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class CurrencyServiceImpl extends AbstractService implements CurrencyService {

    public String g_separator = "，";
    @Autowired
    AreaService areaService;

    @Resource(name = "daoSupport")
    private DaoSupport dao;

    @Override
    public void refreshCache() {
        EntityCache.clearNamespace(getMapperNamespace());
    }

    @Override
    public void saveCostCurrencyDict(List<Currency> listCurrency) {
        for (int i = 0; i < listCurrency.size(); i++) {
            Currency qurRes = (Currency) dao.findForObject(getSqlName("selectByCode"), listCurrency.get(i).getCode());

            if (qurRes != null) {
                throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_CURRENCY_CCODE_EXIST);
            }

        }

        dao.batchInsert(getSqlName("insert"), listCurrency);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_CURRENCY", listCurrency);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_CURRENCY, UserActions.ADD, "新建货币", dataBackup);
    }

    @Override
    public String save(Currency currency) {
        Currency qurRes = (Currency) dao.findForObject(getSqlName("selectByCode"), currency.getCode());

        if (qurRes != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_CURRENCY_CCODE_EXIST);
        }

        checkDataValid(currency);

        dao.save(getSqlName("insert"), currency);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_CURRENCY", currency);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_CURRENCY, UserActions.ADD, "新建货币", dataBackup);
        return currency.getCode();
    }

    @Override
    public void deleteByCode(List<Integer> listIds) {

        if (listIds == null || listIds.size() <= 0) {
            throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY);
        }

        for (int i = 0; i < listIds.size(); i++) {

            Currency currency = (Currency) dao.findForObject(getSqlName("selectByPrimaryKey"), listIds.get(i));

            List<ExchangeRate> roeList = dao.findForList(getSqlName("findRoeByCode"), currency.getCode(), ExchangeRate.class);

            //货币相关汇率已经存在，不能删除相关货币
            if (roeList.size() > 0) {
                throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_CURRENCY_CCODE_NOT_DELETED);
            }
        }

        //String codes = "";

        for (int j = 0; j < listIds.size(); j++) {

            //codes = codes + listIds.get(j) + ",";

            Currency currency = (Currency) dao.findForObject(getSqlName("selectByPrimaryKey"), listIds.get(j));

            if (currency == null) {
                throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_CURRENCY_CCODE_NOT_EXIST);
            }

        }
        dao.delete(getSqlName("deleteByCodes"), listIds);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("DELETE_CURRENCY", listIds);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_CURRENCY, UserActions.DELETE, "删除货币", dataBackup);
    }

    @Override
    public String updateCurrencyById(Currency currency) {
        Currency qurRes = (Currency) dao.findForObject(getSqlName("selectByPrimaryKey"), currency.getId());

        if (qurRes == null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_CURRENCY_CCODE_NOT_EXIST);
        }

        //检查是否修改的code合法
        if (!qurRes.getCode().equalsIgnoreCase(currency.getCode())) {
            List<CurrencyDto> existCodeRecdList = dao.findForList(getSqlName("findCurrencyByCode"), currency.getCode(), CurrencyDto.class);
            if (existCodeRecdList != null && existCodeRecdList.size() > 0) {
                throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_CURRENCY_CCODE_EXIST);
            }
        }

        dao.update(getSqlName("updateByCode"), currency);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("UPDATE_CURRENCY", currency);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_CURRENCY, UserActions.UPDATE, "修改货币", dataBackup);
        return currency.getCode();
    }

    @Override
    public QResultDto findCurrencyList(String q, int pageIndex, int pageSize, String sortName,
                                       boolean isAsc, String language) {

        ParamData pd = this.convertQueryParams(new QueryParams(pageSize, pageIndex, q, sortName, isAsc, language));
        List<CurrencyDto> qurReslist = dao.findForList(getSqlName("CurrencyListPage"), pd, CurrencyDto.class);

        //翻译国家组织字段的id为对应的国际化名称
        for (int i = 0; i < qurReslist.size(); i++) {
            String[] orgArray = qurReslist.get(i).getOrganization().split(g_separator);

            StringBuffer transOrg = new StringBuffer();

            for (int j = 0; j < orgArray.length; j++) {
                String countryName = areaService.getCountryNameByCode(orgArray[j]);
                if (countryName != null && countryName.length() > 0) {

                    transOrg.append(countryName).append(g_separator);
                }
            }
            if (transOrg.length() > 0) {
                String orgStr = transOrg.substring(0, transOrg.length() - 1);
                qurReslist.get(i).setOrganization(orgStr);
            }
        }

        QResultDto qResultDto = new QResultDto();
        qResultDto.setData(qurReslist);
        qResultDto.setPagination(pd.getPagination());

        return qResultDto;
    }

    //    @Override
//    public void batchImport(String filePath){
//        File file = new File(filePath);
//        List<CurrencyDto> list = new ArrayList<CurrencyDto>();
//        if (file.isFile() && file.exists()) {
//            list = CvsUtils.importCurrencyCsv(file);
//        }
//        if (list != null && list.size() > 0) {
//            for (CurrencyDto currencyDto : list) {
//                Currency currency = new Currency();
//                CurrencyI18n currencyI18n = new CurrencyI18n();
//                BeanUtils.copyProperties(currencyDto, currency);
//                BeanUtils.copyProperties(currencyDto, currencyI18n);
//                ParamData pd = new ParamData();
//                pd.put("code", currency.getCode());
//                // 检查数据不能重复
//                Currency currencyExist = (Currency) dao.findForObject("CurrencyMapper.selectByPrimaryKey", pd);
//                if (currencyExist != null) {
//                    throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_CURRENCY_CCODE_EXIST);
//                }
//
//                dao.save("CurrencyMapper.insert", currency);
//
//                dao.save("CurrencyI18nMapper.insert", currencyI18n);
//            }
//        }
//    }
//
//    @Override
//    public void exportFile(String filePath){
//        List<String> dataList = new ArrayList<String>();
//        File file = new File(filePath);
//        List<CurrencyDto> list = dao.findForList("CurrencyMapper.findCurrencyListByCode", "", CurrencyDto.class);
//        if (list != null && list.size() > 0) {
//            for (CurrencyDto currencyDto : list) {
//                String strCurrencyDto;
//                strCurrencyDto = currencyDto.getCode() + "," + currencyDto.getName() + "," + currencyDto.getCsymbol() +
//                        "," + currencyDto.getLanguage();
//                dataList.add(strCurrencyDto);
//            }
//        }
//        CvsUtils.exportCsv(file, dataList);
//    }
    @Override
    public QResultDto findCurencyByCode(String code) {

        List<CurrencyDto> currencyDtoList = dao.findForList(getSqlName("findCurrencyByCode"), code, CurrencyDto.class);

        QResultDto qResultDto = new QResultDto();
        qResultDto.setData(currencyDtoList);

        return qResultDto;
    }

    @Override
    public CurrencyDto findSingleCurencyByCode(String code) {

        String language = PrincipalUtils.getLocalLanguage();

        Map<String, String> paramMap = new HashedMap();

        paramMap.put("code", code);
        paramMap.put("language", language);

        return (CurrencyDto) dao.findForObject(getSqlName("findCurrencyNameByCode"), paramMap);

    }


    /**
     * 根据ID查找对应货币信息
     *
     * @param id :货币id
     */
    @Override
    public Currency findCurrencyById(Integer id) {
        return (Currency) dao.findForObject(getSqlName("selectByPrimaryKey"), id);
    }

    @SuppressWarnings("rawtypes")
    @Override
    public QResultDto findI18nByParam(QueryParams params, boolean unfilled) {

        Map<String, Object> map = new HashMap<>();
        map.put("unfilled", unfilled);

        ParamData pd = this.convertQueryParams(params.put(map));
        List entry = dao.findForList(getSqlName("findI18nByParamListPage"), pd, Map.class);

        QResultDto qResultDto = new QResultDto();
        qResultDto.setData(entry);
        qResultDto.setPagination(pd.getPagination());

        return qResultDto;
    }

    @Override
    public QResultDto findCurrencies(String q, int pageIndex, int pageSize) {

        String language = PrincipalUtils.getLocalLanguage();

        ParamData pd = this.convertQueryParams(new QueryParams(pageSize, pageIndex, q, null, false, language));

        List<CodeNameDto> codeNameDtoList = dao.findForList(getSqlName("findCurrencyByLanguageListPage"), pd, CodeNameDto.class);

        QResultDto qResultDto = new QResultDto();

        qResultDto.setData(codeNameDtoList);

        qResultDto.setPagination(pd.getPagination());

        return qResultDto;
    }

    private void checkDataValid(Currency currency) {

        if (StringUtils.isEmpty(currency.getOrganization())) {

            throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY, "国家");
        }
    }

    @Override
    protected String getMapperNamespace() {
        return "CurrencyMapper";
    }
}
